8.2.2 以并行方式运行测试
正如之前所说,单元测试的目的是独立地进行测试。尽管有些时候,测试套件会因为内部存在依赖关系而无法独立地进行单元测试,但是只要单元测试可以独立地进行,用户就可以通过并行地运行测试用例来提升测试的速度了,本节的内容将向我们展示如何在Go中实现这一点。
首先,在 main_test.go文件
所在的目录中创建一个名为 parallel_test.go
的文件,并在文件中键入代码清单8-4所示的代码。
代码清单8-4 并行测试
package main
import (
"testing"
"time"
)
func TestParallel_1(t *testing.T) { ❶
t.Parallel() ❷
time.Sleep(1 * time.Second)
}
func TestParallel_2(t *testing.T) { ❸
t.Parallel()
time.Sleep(2 * time.Second)
}
func TestParallel_3(t *testing.T) { ❹
t.Parallel()
time.Sleep(3 * time.Second)
}
❶ 模拟需要耗时一秒钟运行的任务
❷ 调用Parallel 函数,以并行方式运行测试用例
❸ 模拟需要耗时2 秒运行的任务
❹ 模拟需要耗时3 秒运行的任务
这个程序利用 time.Sleep
函数,以3个测试用例分别模拟了3个需要耗时1s、2s和3s来运行的任务,并且为了让这些测试用例能够以并行的方式运行,程序还在每个测试用例的开头调用了 testing.T
结构的 Parallel
函数。
现在,我们只要在终端中执行以下命令,Go就会以并行的方式运行测试:
go test –v –short –parallel 3
这条命令中的并行标志 -parallel
用于指示Go以并行方式运行测试用例,而参数 3
则表示我们希望最多并行运行3个测试用例。另外,这条命令还使用了 -short
标志,以便跳过 main_test.go
测试文件中需要长时间运行的测试用例。以下是这个命令的执行结果:
=== RUN TestDecode
--- PASS: TestDecode (0.00s)
=== RUN TestEncode
--- SKIP: TestEncode (0.00s)
main_test.go:24: Skipping encoding for now
=== RUN TestLongRunningTest
--- SKIP: TestLongRunningTest (0.00s)
main_test.go:30: Skipping long-running test in short mode
=== RUN TestParallel_1
=== RUN TestParallel_2
=== RUN TestParallel_3
--- PASS: TestParallel_1 (1.00s)
--- PASS: TestParallel_2 (2.00s)
--- PASS: TestParallel_3 (3.00s)
PASS
ok unit_testing 3.006s
从这个结果我们可以看到, main_test.go文件
和 parallel_test.go文件
中的所有测试用例都被执行了,更为重要的是, parallel_test.go文件
中的3个并行测试用例被同时执行了:尽管这3个并行测试用例的运行时长各有不同,但由于它们是同时运行的,所以这3个测试用例最终都在运行时长最长的测试用例 TestParallel_3
的执行过程中结束了,这也是整个测试最终耗费了3.006 s的原因——其中0.006 s用于执行 main_test.go
中的前几个测试用例,而3 s则用于执行 parallel_test.go
中运行时间最长的测试用例 TestParallel_3
。